package com.dianjing.dianqun.common.thread;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.web.method.HandlerMethod;

import com.dianjing.dianqun.model.SysLogs;
import com.dianjing.dianqun.service.SysLogsService;
import com.dianjing.dianqun.utils.Exceptions;
import com.dianjing.dianqun.utils.SpringUtils;
import com.dianjing.dianqun.utils.StringUtils;

import io.swagger.annotations.ApiOperation;

public class ThreadSaveLog extends Thread {
	private SysLogsService logsService = SpringUtils.getBean(SysLogsService.class);

	public static void saveLog(HttpServletRequest request, String title) {
		saveLog(request, null, null, title);
	}

	/**
	 * 保存日志
	 */
	public static void saveLog(HttpServletRequest request, Object handler, Exception ex, String title) {
		SysLogs log = new SysLogs();
		log.setTitle(title);
		log.setType(ex == null ? SysLogs.TYPE_ACCESS : SysLogs.TYPE_EXCEPTION);
		log.setIp(StringUtils.getRemoteAddr(request));
		log.setUserAgent(request.getHeader("user-agent"));
		log.setUri(request.getRequestURI());
		log.setParams(setParames(request.getParameterMap()));
		log.setMethod(request.getMethod());
		log.setInsertDate(new Date());
		// 异步保存日志
		new ThreadSaveLog(log, handler, ex).start();
	}

	private SysLogs log;
	private Object handler;
	private Exception ex;

	public ThreadSaveLog(SysLogs log, Object handler, Exception ex) {
		super(ThreadSaveLog.class.getSimpleName());
		this.log = log;
		this.handler = handler;
		this.ex = ex;
	}

	@Override
	public void run() {
		if (StringUtils.isBlank(log.getTitle())) {
			String apiInfo = "";
			if (handler instanceof HandlerMethod) {
				Method m = ((HandlerMethod) handler).getMethod();
				ApiOperation rp = m.getAnnotation(ApiOperation.class);
				apiInfo = (rp != null ? StringUtils.join(rp.value(), " ") : "");
			}
			log.setTitle(apiInfo);
		}
		// 如果有异常，设置异常信息
		log.setException(Exceptions.getStackTraceAsString(ex));
		// 如果无标题并无异常日志，则不保存信息
		if (StringUtils.isBlank(log.getTitle()) && StringUtils.isBlank(log.getException())) {
			return;
		}
		// 保存日志信息
		logsService.insert(log);
	}

	private static String setParames(Map<String, String[]> paramMap) {
		if (paramMap == null) {
			return "";
		}
		StringBuilder params = new StringBuilder();
		for (Map.Entry<String, String[]> param : ((Map<String, String[]>) paramMap).entrySet()) {
			params.append(("".equals(params.toString()) ? "" : "&") + param.getKey() + "=");
			String paramValue = (param.getValue() != null && param.getValue().length > 0 ? param.getValue()[0] : "");
			params.append(StringUtils.abbr(StringUtils.endsWithIgnoreCase(param.getKey(), "password") ? "" : paramValue,200));
		}
		return params.toString();
	}
}
